/**
 * 
 */
package org.t2.backstage.module.player.service;

import java.util.ArrayList;
import java.util.List;

import org.banish.sql.core.dao.Dao;
import org.banish.sql.core.datasource.IDataSource;
import org.banish.sql.core.util.QuerySet;
import org.gaming.ruler.schedule.LoopingTask;
import org.gaming.service.repository.Repository;
import org.gaming.service.service.AbstractService;
import org.gaming.tool.DateTimeUtil;
import org.gaming.tool.GsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.t2.backstage.module.gameserver.model.GameServer;
import org.t2.backstage.module.gameserver.service.DataBaseManager;
import org.t2.backstage.module.gameserver.service.GameServerService;
import org.t2.backstage.module.player.model.FirstPayRemain;
import org.t2.backstage.module.player.struct.FirstPayRemainCount;
import org.t2.backstage.module.system.model.SystemCounter;
import org.t2.backstage.module.system.service.SystemCounterService;

import sh.t2.share.module.player.log.PlayerLoginLog;

/**
 * 
 */
@Service
public class FirstPayRemainService extends AbstractService<FirstPayRemain> {

	@Autowired
	private GameServerService gameServerService;
	@Autowired
	private DataBaseManager dataBaseManager;
	@Autowired
	private SystemCounterService systemCounterService;
	
	public void insertUpdate(List<FirstPayRemain> remains) {
		this.repository().getBaseDao().insertUpdate(remains);
	}
	
	@LoopingTask(name = "PlayerTimer-首冲用户留存", spaceTime = DateTimeUtil.ONE_SECOND_MILLIS * 10, execGroup = 5)
	private void runInSchedule() {
		SystemCounter systemCounter = systemCounterService.instance();
		if(DateTimeUtil.currMillis() < systemCounter.getFirstPayRemainTime()) {
			return;
		}
		systemCounter.setFirstPayRemainTime(DateTimeUtil.tomorrowZeroMillis());
		systemCounterService.update(systemCounter);
		
		countPayRemain(DateTimeUtil.todayZeroMillis());
	}
	
	public void countPayRemain(long dateTimeMillis) {
		//今天统计的是昨天的数据
		dateTimeMillis = dateTimeMillis - DateTimeUtil.ONE_DAY_MILLIS;
		
		String yearMonth = DateTimeUtil.formatMillis(DateTimeUtil.YYYYMM, dateTimeMillis);
		String tableName = Repository.getTableName(PlayerLoginLog.class) + "_" + yearMonth;
		
		String currYMD = DateTimeUtil.formatMillis(DateTimeUtil.YYYY_MM_DD, dateTimeMillis);
		logger.info("开始{}的首次付费留存统计", currYMD);
		
		for(GameServer gameServer : gameServerService.getEntityList(0)) {
			logger.info("进行服务器{}-{}的首次付费留存统计", gameServer.getId(), gameServer.getName());
			queryFristPayLog(gameServer, tableName, dateTimeMillis);
		}
		logger.info("完成{}的付费留存统计", currYMD);
	}
	
	public void queryFristPayLog(GameServer gameServer, String tableName, long currMillis) {
		IDataSource dataBase = dataBaseManager.getLogDb(gameServer.getId());
		if(dataBase == null) {
			logger.error("服务器{}-{}的首次付费留存统计中，未找到数据库连接信息", gameServer.getId(), gameServer.getName());
			return;
		}
		
		String currYMD = DateTimeUtil.formatMillis(DateTimeUtil.YYYY_MM_DD, currMillis);
		long nextDateTime = currMillis + DateTimeUtil.ONE_DAY_MILLIS;
		String nextYMD = DateTimeUtil.formatMillis(DateTimeUtil.YYYY_MM_DD, nextDateTime);
		
		String remainSql = "SELECT "
				+ "channel_id AS channelId, "
				+ "first_pay_date AS firstDate, "
				+ "DATEDIFF(login_date, first_pay_date) AS dayCount, "
				+ "count(DISTINCT player_id) AS playerCount "
				+ "FROM " + tableName + " ";
		QuerySet querySet = new QuerySet();
		querySet.addCondition("first_pay_date > 0");
		querySet.addCondition("login_time >= ?", currYMD);
		querySet.addCondition("login_time < ?", nextYMD);
		querySet.groupBy("GROUP BY channel_id, first_pay_date, DATEDIFF(login_date, first_pay_date)");
		querySet.formWhere();
		
		String sql = remainSql + querySet.getWhere();
		try {
			List<FirstPayRemainCount> logs = Dao.queryAliasObjects(dataBase, FirstPayRemainCount.class, sql, querySet.getParams());
			
			List<FirstPayRemain> remainList = new ArrayList<>();
			for(FirstPayRemainCount log : logs) {
				FirstPayRemain remain = new FirstPayRemain();
				remain.setChannelId(log.getChannelId());
				remain.setServerUid(gameServer.getId());
				remain.setFirstDate(log.getFirstDate());
				remain.setDayCount(log.getDayCount());
				remain.setPlayerCount(log.getPlayerCount());
				remainList.add(remain);
			}
			this.insertUpdate(remainList);
		} catch (Exception e) {
			logger.error("数据库连不上" + GsonUtil.toJson(dataBase));
		}
	}
	
	public List<FirstPayRemain> queryRemain(QuerySet query) {
		return this.repository().getBaseDao().queryListWhere(query.getWhere(), query.getParams());
	}

	@Override
	public void mergeServer(int mergeDbZoneId) {
		//不必理会
	}
}
